home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2005 December / DPPCPRO1205.ISO / Essentials / Programming / Basic4GL / Setup Basic4GL v2.3.1.exe / $INSTDIR / Programs / AsteroidDemo2.gb < prev    next >
Encoding:
Text File  |  2005-07-29  |  16.7 KB  |  475 lines

  1. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  2. ' Asteroid demo
  3.  
  4.     ' Screen mode
  5.     TextMode (TEXT_BUFFERED)        ' Don't draw sprites until explicitly told to do so
  6.     ResizeSpriteArea (800, 600)
  7.     
  8.     ' Player state
  9.     struc SPlayer
  10.         dim sprite
  11.         dim index
  12.         dim lives, score, deadCounter, invincibleCounter, ingame
  13.         dim leftKey, rightKey, thrustKey, shootKey
  14.         dim wasShooting
  15.         dim col#(3)
  16.     endstruc
  17.     
  18.     ' Bullets
  19.     struc SBullet
  20.         dim sprite, life, SPlayer &player
  21.     endstruc
  22.     
  23.     ' Asteroids
  24.     struc SAsteroid
  25.         dim sprite, dir#
  26.     endstruc
  27.     
  28.     ' Initialise gamestate
  29.     const maxPlayers = 2
  30.     const maxBullets = 200
  31.     const maxAsteroids = 200
  32.     const maxExplosions = 200
  33.     dim SPlayer players(maxPlayers), SPlayer &player 
  34.     dim SBullet bullets(maxBullets), SBullet &bullet, bulletCount
  35.     dim SAsteroid asteroids(maxAsteroids), SAsteroid &asteroid, SAsteroid &newAsteroid, asteroidCount
  36.     dim explosions(maxExplosions), explosionCount
  37.     dim levelCounter, counter
  38.     dim level, dead
  39.     dim i, j, k, temp#, vec#(1), centreVec#(1), size#, maxSize#, count
  40.     
  41.     ' Sprite textures
  42.     dim shipTex, rockTex, ballTex 
  43.     shipTex = LoadTexture ("data\F117.png")
  44.     rockTex = LoadTexture ("data\asteroid.png")
  45.     ballTex = LoadTexture ("data\ball.png")
  46.     
  47.     ' Animations
  48.     dim explodeTex (ImageStripFrames ("data\explode.png") - 1)
  49.     explodeTex = LoadMipmapImageStrip ("data\explode.png") 
  50.     
  51.     ' Tile textures
  52.     dim tileTex (ImageStripFrames ("data\spacetiles.png") - 1)
  53.     tileTex = LoadMipmapImageStrip ("data\spaceTiles.png")
  54.     
  55.     ' Setup tile map
  56.     dim tileMap, t(9)(9)
  57.     tileMap = NewTileMap (tileTex)  
  58.     data 2,2,3,1,2,1,1,3,2,3
  59.     data 3,3,2,3,2,3,2,3,2,2
  60.     data 3,1,2,3,3,4,3,2,3,3
  61.     data 2,1,4,2,5,3,3,1,2,1
  62.     data 2,3,2,3,3,1,2,3,3,3
  63.     data 2,2,2,1,2,2,3,1,3,2
  64.     data 3,1,3,1,2,2,2,2,1,3
  65.     data 2,1,2,4,1,3,2,3,2,3
  66.     data 2,2,3,2,3,3,2,3,3,1
  67.     data 3,2,1,2,3,2,1,2,2,1
  68.     for i = 0 to 9
  69.         for j = 0 to 9
  70.             read t(i)(j)
  71.         next
  72.     next
  73.     SprSetTiles (t)
  74.     SprSetZOrder (100)      ' Push tile map to back
  75.     SprSetScale (2)
  76.     
  77.     ' Sound effects
  78.     dim shootSound, explodeSound
  79.     shootSound   = LoadSound ("sounds\laser.wav")
  80.     explodeSound = LoadSound ("sounds\gunshot5.wav")
  81.     
  82.     ' Setup keys
  83.     players(1).index     = 1
  84.     players(1).leftKey   = VK_LEFT
  85.     players(1).rightKey  = VK_RIGHT
  86.     players(1).thrustKey = VK_UP
  87.     players(1).shootKey  = VK_SPACE
  88.     players(1).col#      = vec4(.7,.7,.6,1)
  89.     players(2).index     = 2
  90.     players(2).leftKey   = Asc("A")
  91.     players(2).rightKey  = Asc("D")
  92.     players(2).thrustKey = Asc("W")
  93.     players(2).shootKey  = Asc("F")
  94.     players(2).col#      = vec4(.3,.6,.8,1)
  95.     
  96.     goto start
  97.     
  98.     return
  99.     
  100. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  101. ' Routines
  102. NewPlayer:
  103.  
  104.     ' Create player sprite
  105.     player.sprite   = NewSprite (shipTex)
  106.     SprSetSize (32, 32)    
  107.     SprSetColor (player.col#)
  108.     
  109.     ' Initialise player settings
  110.     player.ingame   = true
  111.     player.lives    = 3
  112.     player.score    = 0
  113.     
  114.     ' Spawn player at centre
  115.     gosub Spawn
  116.     return
  117.     
  118. Spawn:
  119.  
  120.     ' Set player alive again
  121.     player.deadCounter       = 0
  122.     BindSprite (player.sprite)
  123.     SprSetVisible (true)     ' Show sprite
  124.     
  125.     ' Place player at centre of screen
  126.     gosub CentrePlayer
  127.     return
  128.     
  129. CentrePlayer:
  130.     player.invincibleCounter = 300
  131.     BindSprite (player.sprite)
  132.     SprSetPos   (SpriteAreaWidth () / 2, SpriteAreaHeight () / 2)
  133.     SprSetAngle (0)
  134.     SprSetVel   (0, 0)
  135.     return
  136.     
  137. Clamp:
  138.     ' Clamp sprite s to screen range
  139.     if SprX () < -32 then
  140.         SprSetX (SprX () + SpriteAreaWidth () + 64)
  141.     endif
  142.     if SprX () >= SpriteAreaWidth () + 32 then
  143.         SprSetX (SprX () - (SpriteAreaWidth () + 64))
  144.     endif
  145.     if SprY () < -32 then
  146.         SprSetY (SprY () + SpriteAreaHeight () + 64)
  147.     endif
  148.     if SprY () >= SpriteAreaHeight () + 32 then
  149.         SprSetY (SprY () - (SpriteAreaHeight () + 64))
  150.     endif
  151.     return
  152.     
  153. MakeExplosion:
  154.     
  155.     ' Make explosion at vec#
  156.     if explosionCount < maxExplosions then        
  157.         explosionCount = explosionCount + 1
  158.         explosions (explosionCount) = NewSprite (explodeTex)
  159.         SprSetSize (64, 64)
  160.         SprSetPos (vec#)
  161.         SprSetAnimSpeed (.4 / size#)
  162.         SprSetAnimLoop (false)
  163.         SprSetScale (size#)
  164.     endif
  165.     return
  166.     
  167. MakeExplosions:
  168.     
  169.     ' Make explosions
  170.     for k = 1 to count
  171.         vec#  = centreVec# + vec2 (Rnd () % 21 - 10, Rnd () % 21 - 10)
  172.         size# = maxSize# * (Rnd () % 6 + 5) / 10.0
  173.         gosub MakeExplosion
  174.     next
  175.     return
  176.     
  177. MakeSmoke:
  178.     if explosionCount < maxExplosions then        
  179.         explosionCount = explosionCount + 1
  180.         explosions (explosionCount) = NewSprite (explodeTex)
  181.         SprSetSize (64, 64)
  182.         SprSetPos (vec#)
  183.         SprSetFrame (10)
  184.         SprSetAnimSpeed (.1)
  185.         SprSetAnimLoop (false)
  186.         SprSetScale (.4)
  187.     endif
  188.     return    
  189.  
  190. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  191. ' Mainloop
  192. start:
  193.  
  194. NextLevel:
  195.  
  196.     level = level + 1
  197.     levelCounter = 200
  198.     
  199.     ' Create asteroids
  200.     asteroidCount = level * 2 + 1
  201.     for i = 1 to asteroidCount
  202.         &asteroid = &asteroids (i)
  203.         asteroid.sprite = NewSprite (rockTex)
  204.         SprSetSize (24, 24)
  205.         SprSetScale (4)
  206.         SprSetZOrder (SprScale ())
  207.         SprSetPos (rnd () % int (SpriteAreaWidth ()), rnd () % int (SpriteAreaHeight ()))
  208.         SprSetSpin (.25)
  209.         asteroid.dir# = rnd () % 360
  210.         SprSetVel (MatrixRotateZ (asteroid.dir#) * vec2 (0, 2) / SprScale ())
  211.     next
  212.                         
  213.     ' Delete player bullets
  214.     for i = 1 to bulletCount
  215.         DeleteSprite (bullets (i).sprite)
  216.     next
  217.     bulletCount = 0
  218.     
  219.     ' Delete explosions
  220.     for i = 1 to explosionCount
  221.         DeleteSprite (explosions (i))
  222.     next
  223.     explosionCount = 0
  224.     
  225.     ' Recentre players
  226.     for i = 1 to maxPlayers
  227.         &player = &players (i)
  228.         if player.inGame and player.deadCounter = 0 then
  229.             gosub CentrePlayer
  230.         endif
  231.     next 
  232.  
  233.     locate 16, 12: print "Level " + level
  234.     DrawText ()
  235.     Sleep (1000)
  236.  
  237.     while asteroidCount > 0 or levelCounter > 0        
  238.         if asteroidCount = 0 then 
  239.             levelCounter = levelCounter - 1
  240.         endif
  241.         
  242.         ' Update gameplay
  243.         Joy_Keys ()
  244.         while SyncTimer (10)
  245.             counter = counter + 1
  246.             AnimateSprites ()
  247.             
  248.             ' Move players   
  249.             for i = 1 to MaxPlayers
  250.                 &player = &players (i)
  251.  
  252.                 ' Counters
  253.                 if player.inGame then
  254.                     if player.deadCounter > 0 then
  255.                         player.deadCounter = player.deadCounter - 1
  256.                         if player.deadCounter = 0 then
  257.                             if player.lives > 0 then                            
  258.                                 player.lives = player.lives - 1
  259.                                 gosub Spawn
  260.                             else
  261.                                 player.ingame = false
  262.                             endif
  263.                         endif
  264.                     endif
  265.                     if player.invincibleCounter > 0 then
  266.                         player.invincibleCounter = player.invincibleCounter - 1
  267.                         BindSprite (player.sprite)
  268.                         SprSetVisible ((player.invincibleCounter and 16) = 0)
  269.                     endif
  270.                 endif
  271.  
  272.                 ' Shooting/spawning
  273.                 if ScanKeyDown (player.shootKey) then
  274.                     if not player.wasShooting then                    
  275.                         if not player.inGame then
  276.                         
  277.                             ' Put player in game
  278.                             gosub NewPlayer
  279.                         else
  280.                             if player.deadCounter = 0 and player.invincibleCounter = 0 and bulletCount < maxBullets then
  281.                             
  282.                                 ' Shoot bullet
  283.                                 bulletCount = bulletCount + 1
  284.                                 &bullet = &bullets (bulletCount)
  285.                                 bullet.sprite = NewSprite (ballTex)
  286.                                 SprSetZOrder (10)
  287.                                 SprSetSize (16, 16)
  288.                                 SprSetPos (SprPos (player.sprite))
  289.                                 SprSetVel (SprVel (player.sprite) + MatrixRotateZ (SprAngle (player.sprite)) * vec2 (0, -3.5))
  290.                                 bullet.life = 100
  291.                                 &bullet.player = &player
  292.                                 PlaySound (shootSound)
  293.                             endif
  294.                         endif
  295.                     endif  
  296.                     player.wasShooting = true
  297.                 else
  298.                     player.wasShooting = false
  299.                 endif
  300.                 
  301.                 if player.inGame and player.deadCounter = 0 then
  302.                     
  303.                     ' Moving
  304.                     BindSprite (player.sprite)
  305.                     if ScanKeyDown (player.leftKey) then
  306.                         SprSetAngle (SprAngle () - 3)
  307.                     endif
  308.                     if ScanKeyDown (player.rightKey) then
  309.                         SprSetAngle (SprAngle (player.sprite) + 3)
  310.                     endif
  311.                     if ScanKeyDown (player.thrustKey) then
  312.                         SprSetVel (SprVel () + MatrixRotateZ (SprAngle ()) * vec2 (0, -.035))
  313.                         vec# = SprPos () + MatrixRotateZ (SprAngle ()) * vec2 (0, 15)
  314.                         if (counter and 7) = 0 then
  315.                             gosub MakeSmoke
  316.                         endif
  317.                     endif
  318.                     gosub Clamp
  319.  
  320.                     ' Check for collisions with asteroids
  321.                     if player.invincibleCounter = 0 then
  322.                         for j = 1 to asteroidCount 
  323.                             &asteroid = &asteroids (j)
  324.                             BindSprite (asteroid.sprite)
  325.                             if Length (SprPos () - SprPos (player.sprite)) < SprScale () * SprXSize () / 2 + 4 then                                        
  326.                                 
  327.                                 ' Make explosions
  328.                                 centrevec# = SprPos (player.sprite)
  329.                                 count      = 5
  330.                                 maxSize#   = 2
  331.                                 gosub MakeExplosions
  332.                                 
  333.                                 ' Explosion sound
  334.                                 PlaySound (explodeSound)
  335.                                 
  336.                                 ' Hide player sprite
  337.                                 BindSprite (player.sprite)
  338.                                 SprSetVisible (false)
  339.                                 
  340.                                 ' Mark player as dead 
  341.                                 player.deadCounter = 300
  342.                             endif
  343.                         next                                
  344.                     endif             
  345.                 endif
  346.             next
  347.             
  348.             ' Move bullets
  349.             i = 1
  350.             while i <= bulletCount
  351.                 &bullet = &bullets(i)
  352.                 
  353.                 ' Clamp bullet pos
  354.                 BindSprite (bullet.sprite)
  355.                 gosub Clamp
  356.                 
  357.                 ' Bullet has only limited life
  358.                 bullet.life = bullet.life - 1
  359.                 dead = bullet.life <= 0
  360.                 
  361.                 ' Test for collisions with asteroids
  362.                 j = 1
  363.                 while j <= asteroidCount
  364.                     &asteroid = &asteroids (j)
  365.                     BindSprite (asteroid.sprite)
  366.                     if Length (SprPos () - SprPos (bullet.sprite)) < SprScale () * SprXSize () / 2 then                                        
  367.  
  368.                         ' Make explosion
  369.                         centrevec# = SprPos ()
  370.                         count = SprScale () * 2
  371.                         maxSize# = (SprScale () + 1) * 0.3
  372.                         gosub MakeExplosions
  373.                         
  374.                         ' Need to rebind after explosion routine
  375.                         BindSprite (asteroid.sprite)
  376.  
  377.                         ' Destroy small asteroids
  378.                         if SprScale () <= 1 then
  379.                             DeleteSprite (asteroid.sprite)
  380.                             asteroid = asteroids (asteroidCount)
  381.                             asteroidCount = asteroidCount - 1
  382.                             if asteroidCount = 0 then
  383.                                 bullet.player.score = bullet.player.score + 200
  384.                             endif
  385.                             bullet.player.score = bullet.player.score + 20
  386.                         else
  387.                             ' Otherwise split them
  388.                             ' Shrink existing one
  389.                             SprSetScale (SprScale () / 2)
  390.                             SprSetZOrder (SprScale ())
  391.                             SprSetSpin (SprSpin () * 4)
  392.                             
  393.                             ' Create new duplicate asteroid
  394.                             asteroidCount = asteroidCount + 1
  395.                             &newAsteroid = &asteroids (asteroidCount)
  396.                             newAsteroid = asteroid
  397.                             newAsteroid.sprite = NewSprite ()
  398.                             CopySprite (asteroid.sprite)
  399.                       
  400.                             ' Add some random directional deviation
  401.                             temp# = rnd () % 35 + 10
  402.                             asteroid.dir#       = asteroid.dir#     + temp#
  403.                             newAsteroid.dir#    = newAsteroid.dir#  - temp#
  404.                             
  405.                             ' Recalculate velocities
  406.                             BindSprite (asteroid.sprite)
  407.                             SprSetVel (MatrixRotateZ (asteroid.dir#) * vec2 (0, 2) / SprScale ())
  408.                             BindSprite (newAsteroid.sprite)
  409.                             SprSetVel (MatrixRotateZ (newasteroid.dir#) * vec2 (0, 2) / SprScale ())                            
  410.                             bullet.player.score = bullet.player.score + 10  
  411.                         endif
  412.                         PlaySound (explodeSound)
  413.                         j = asteroidCount + 1
  414.                         dead = true
  415.                     else
  416.                         j = j + 1
  417.                     endif
  418.                 wend
  419.  
  420.                 if dead then    
  421.                     
  422.                     ' Delete bullet
  423.                     vec# = SprPos (bullet.sprite)
  424.                     gosub MakeSmoke
  425.                     DeleteSprite (bullet.sprite)
  426.                     bullet = bullets (bulletCount)
  427.                     bulletCount = bulletCount - 1
  428.                 else
  429.                     i = i + 1
  430.                 endif
  431.             wend
  432.             
  433.             ' Move asteroids
  434.             for i = 1 to asteroidCount
  435.                 BindSprite (asteroids (i).sprite)
  436.                 gosub Clamp
  437.             next
  438.             
  439.             ' Remove completed explosion animations
  440.             i = 1
  441.             while i <= explosionCount
  442.                 if SprAnimDone (explosions (i)) then
  443.                     DeleteSprite (explosions (i))
  444.                     explosions (i) = explosions (explosionCount)
  445.                     explosionCount = explosionCount - 1
  446.                 else
  447.                     i = i + 1
  448.                 endif
  449.             wend
  450.             
  451.             ' Animate tile map
  452.             BindSprite (tileMap)
  453.             SprSetPos (SprPos () + vec2 (.1, .2))
  454.         wend
  455.         
  456.         ' Update display
  457.         cls
  458.         if players (1).inGame then
  459.             locate 0, 0: print "Score=" + players (1).score
  460.             locate 0, 1: print "Lives=" + players (1).lives
  461.         endif
  462.         if players (2).inGame then
  463.             locate 30, 0: print "Score=" + players (2).score
  464.             locate 30, 1: print "Lives=" + players (2).lives
  465.         endif
  466.         if not (players (1).inGame or players (2).inGame) then 
  467.             locate 10, 12: print "Press Space to Start"
  468.         endif
  469.  
  470.         ' Draw sprites
  471.         DrawText ()
  472.     wend
  473.  
  474.     goto NextLevel
  475.